サーバーレスアーキテクチャで翻訳 Web API を構築するハンズオンをやってみた
サーバーレスアーキテクチャを基礎から復習したかったです。手を動かしたい派なので初心者向けのハンズオンをやってみました。なにを復習したら良いのかはやってみてから考えることにしました。
以下の構成を手を動かして作ります。
画像引用: ハンズオンのアンケート回答後にダウンロードできる資料より
やってみた感想
- 2019年に収録されたハンズオン動画のため一部マネージメントコンソールのUIに変更は見られるものの構築する上では支障はありませんでした(2021年11月現在)
- API Gateway プロキシ統合のLambda(Python)と、SDKを使い他のAWSサービスの呼び出しを試せる
- 以下のサービスの連携を簡単に体験したい初心者にオススメ
- API Gateway
- Lambda
- Translate
- DyanamoDB
- ハンズオンを完走するまでの所要時間は約1時間30分でした
ハンズオン記事のリンク
過去にオススメと紹介されている記事もあります。
AWS Hands-on for Beginners とは
ハンズオン動画(YouTube)を見ながら実際に手を動かして学ぶAWSが提供しているコンテンツです。
AWS Hands-on for Beginners シリーズのリンク
AWS Hands-on for Beginners Serverless #1
テーマの「サーバーレスアーキテクチャで翻訳 Web API を構築する」は座学パートと、ハンズオンパートで構成されています。後で振り返りたい日がくるかもしれないのでハンズオンパートで実施した内容を残しておきます。
座学パート
動画を見て丁寧な説明を聞きます。
1 Serverless アーキテクチャの概要
2 AWS Lambda の概要
5 Amazon API Gateway の概要
8 Amazon DynamoDB の概要
ハンズオンパート
3. Lambda を単体で使ってみる
初っ端からハンズオン通りではなくarm64アーキテクチャ(Graviton2)のLambdaを使ってみたいので選択しました。問題なくハンズオンを完走できています。
event
の中身を確認する
import json import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): logger.info(event) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
テスト結果から確認できたり、
CloudWatch Logsから実行結果を確認できることを確認しました。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | timestamp | message | |---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1636549374190 | START RequestId: d71278a5-e01e-4eb0-8b19-592d57a5944b Version: $LATEST | | 1636549374190 | [INFO] 2021-11-10T13:02:54.190Z d71278a5-e01e-4eb0-8b19-592d57a5944b {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} | | 1636549374193 | END RequestId: d71278a5-e01e-4eb0-8b19-592d57a5944b | | 1636549374193 | REPORT RequestId: d71278a5-e01e-4eb0-8b19-592d57a5944b Duration: 1.30 ms Billed Duration: 2 ms Memory Size: 256 MB Max Memory Used: 38 MB Init Duration: 106.98 ms | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4. 他のサービスを呼び出してみる
LambdaからTranslateを呼び出して「おはよう」を「Good morning」へ変換しました。
import json import boto3 translate = boto3.client('translate') def lambda_handler(event, context): input_text = 'おはよう' response = translate.translate_text( Text=input_text, SourceLanguageCode='ja', TargetLanguageCode='en' ) output_text = response.get('TranslatedText') return { 'statusCode': 200, 'body': json.dumps({ 'output_text': output_text }) }
{ "statusCode": 200, "body": "{\"output_text\": \"Good morning\"}" }
6. API Gateway を単体で使ってみる
Mockデータを返すAPIを作成します。API GatewayからLambdaを呼び出すのは次の章です。
統合レスポンスのマッピングテンプレートからapplication/json
を編集しMockデータを作成。
{ "statusCode": 200, "body":{ { "report_id": 5, "report_title": "Hello, Abashiri" }, { "report_id": 7, "report_title": "こんにちは 網走" }, } }
ステージから対象のURLを呼び出し確認します。
Webブラウザに以下の結果が表示され実行確認完了です。
ここまででちょうど1時間くらいです。
7. API Gateway と Lambda を組み合わせる
ハンズオンでは試しやすいようにPOST
ではなくGET
メソッドを採用している。
テストイベントはイベントテンプレートからapigateway-aws-proxy
を選択。
input_text
で受け取ります。
import json import boto3 translate = boto3.client('translate') def lambda_handler(event, context): input_text = event['queryStringParameters']['input_text'] response = translate.translate_text( Text=input_text, SourceLanguageCode='ja', TargetLanguageCode='en' ) output_text = response.get('TranslatedText') return { 'statusCode': 200, 'body': json.dumps({ 'output_text': output_text }), 'isBase64Encoded': False, 'headers': {} }
{ "statusCode": 200, "body": "{\"output_text\": \"Hi\"}", "isBase64Encoded": false, "headers": {} }
API GatewayからLambdaを呼び出した結果。
9. Amazon DynamoDB ハンズオン① テーブルを作ってみる
DynamoDBでテーブルを作成し、手動で項目をひとつ追加するだけです。
10. API Gateway と Lambda と DynamoDB を組み合わせる
今までの登場した要素をすべて繋ぎ合わせます。
import json import boto3 import datetime translate = boto3.client('translate') dynamodb = boto3.resource('dynamodb') dynamodb_translate_history_table = dynamodb.Table('translate-history') def lambda_handler(event, context): input_text = event['queryStringParameters']['input_text'] response = translate.translate_text( Text=input_text, SourceLanguageCode='ja', TargetLanguageCode='en' ) output_text = response.get('TranslatedText') dynamodb_translate_history_table.put_item( Item = { 'timestamp': datetime.datetime.now().strftime("%Y%m%d%H%M%S"), 'input_text': input_text, 'output_text': output_text } ) return { 'statusCode': 200, 'body': json.dumps({ 'output_text': output_text }), 'isBase64Encoded': False, 'headers': {} }
{ "statusCode": 200, "body": "{\"output_text\": \"Hi\"}", "isBase64Encoded": false, "headers": {} }
ブラウザから実行
変換の記録はDynamoDBに保存されています。
落ち穂拾い
最後のまとめパートです。
- Lambdaのグローバルスコープと、ローカルスコープの違い説明
- サンプルコードは例外処理実装していないことの説明
- 今後の勉強していくと良い方向性性の示唆
おわりに
ハンズオンは説明も丁寧な上にハマらない配慮がされており時間が溶けずに済むのが良かったです。普段はハマってから何かを見出して強くなるスタイルで生きているので、なにやるにしても上手くいかず時間がなくなっていきます。 ハンズオンを終えたあとに当初の目的であったサーバレスアーキテクチャの復習には以下のリンクが良いかなと思いました。
2021/11/16追記本記事の内容をモダンなデプロイ方法で試す続編のハンズオンもやってみましたのでご紹介します。